#include <QApplication>
#include <QProgressDialog>

#include "diutils.h"
#include "qhexedit2/chunks.h"

namespace {
    const int BUFFER_SIZE = 0x10000;
}

QByteArray toHex(const QByteArray& ba, char separator, int count)
{
    if (!ba.size())
        return QByteArray();

    if (count <= 0 || count > ba.size())
        count = ba.size();

    const int length = separator ? (ba.size() * 3 - 1) : (ba.size() * 2);
    QByteArray hex(length, Qt::Uninitialized);
    char *hexData = hex.data();
    const uchar *data = (const uchar *)ba.data();
    for (int i = 0, o = 0; i < count; ++i) {
        hexData[o++] = toHexLower(data[i] >> 4);
        hexData[o++] = toHexLower(data[i] & 0xf);

        if ((separator) && (o < length))
            hexData[o++] = separator;
    }
    return hex;
}

qint64 forwardFind(QFile& file, const QByteArray &ba, qint64 from)
{
    QProgressDialog progress(qApp->activeWindow());
    progress.setWindowTitle(QObject::tr("Progress"));
    progress.setLabelText(QObject::tr("Forward Find..."));
    progress.setRange(0, 0);
    progress.setModal(true);

    qint64 result = -1;
    QByteArray buffer;
    Chunks chunks(file, 0);
    for (qint64 pos = from; pos < chunks.size(); pos += BUFFER_SIZE) {
        buffer = chunks.data(pos, BUFFER_SIZE + ba.size() - 1);
        int findPos = buffer.indexOf(ba);
        if (findPos >= 0) {
            result = pos + (qint64)findPos;
            break;
        }

        qApp->processEvents();
        if (progress.wasCanceled())
            break;
    }

    return result;
}

qint64 backwardFind(QFile &file, const QByteArray &ba, qint64 from)
{
    QProgressDialog progress(qApp->activeWindow());
    progress.setWindowTitle(QObject::tr("Progress"));
    progress.setLabelText(QObject::tr("Backward Find..."));
    progress.setRange(0, 0);
    progress.setModal(true);

    qint64 result = -1;
    QByteArray buffer;
    Chunks chunks(file, 0);
    for (qint64 pos = from; pos > 0; pos -= BUFFER_SIZE) {
        qint64 sPos = pos - BUFFER_SIZE - (qint64)ba.size() + 1;
        if (sPos < 0)
            sPos = 0;
        buffer = chunks.data(sPos, pos - sPos);
        int findPos = buffer.lastIndexOf(ba);
        if (findPos >= 0) {
            result = sPos + (qint64)findPos;
            break;
        }
        qApp->processEvents();
        if (progress.wasCanceled())
            break;
    }

    return result;
}
